/*  LDRize IDE 0.1.3
 *  (c) 2007 Shinichi Tomita (shinichi.tomita@gmail.com)
 *
 *  LDRize IDE is freely distributable under the terms of an MIT-style license.
 *  For details, see the LDRize IDE web site: http://code.google.com/p/ldride/
/*--------------------------------------------------------------------------*/

Ext.onReady(function() {

var doc, iframe, form, cxpathInput, xpathInput, clearBtn;

function init() {

  form = new Ext.form.FormPanel({
    labelWidth: 150,
    title: 'LDRize IDE',
    frame : true,
    bodyStyle:'padding:10px 10px 0',
    items: [
      { hideLabel : true,
        name : 'iframe',
        anchor : '100% -60',
        html : '<iframe id="iframe" style="width:99%;height:98%;background-color:white" ></iframe>'
      },
      cxpathInput = new Ext.form.TextField({
        fieldLabel : '(paragraph container)',
        anchor : '100%'
      }),
      xpathInput = new Ext.form.TextField({
        fieldLabel : 'paragraph',
        anchor : '100%'
      })
    ],
    buttons : [
      clearBtn = new Ext.Button({ text : 'Clear', handler : clearSelection })
    ]
  });

  var viewport = new Ext.Viewport({ layout :'fit', items : form });

  cxpathInput.on('change', evalContainerPath);
  xpathInput.on('change', evalXPath);

}

function loadContent(contentURL) {
  iframe = $('#iframe').get(0);
  iframe.contentWindow.location.href = contentURL || location.href;

  if ($.browser.msie) { // if IE
    $(iframe).bind('readystatechange', function () {
      if (iframe.readyState == "complete") {
        onContentReady();
        iframe.onreadystatechange = null;
      }
    });
  } else {
    $(iframe).bind('load', onContentReady);
  }
}

function onContentReady() {
  doc = iframe.contentWindow.document;
  var scriptContainerElem = $(doc.documentElement).find('head,body').get(0);
  var script = doc.createElement('script');
  script.type = 'text/javascript';
  script.src = baseURL + '/jsxpath/javascript-xpath.js';
  scriptContainerElem.appendChild(script);

  $(doc.body)
    .mouseover(handleMouseOver)
    .mouseout(handleMouseOut)
    .click(handleClick);
}


var mode = 'select-container';
var containerElem = null;

function handleMouseOver(event) {
  switch (mode) {
    case 'select-container' :
      overrideStyle(event.target, { 
        borderColor : '#f00', 
        borderWidth : '1px', 
        borderStyle : 'solid' 
      });
    case 'select-paragraph' :
      if (isInContainer(event.target)) {
        overrideStyle(event.target, { 
          borderColor : '#f00', 
          borderWidth : '1px', 
          borderStyle : 'solid' 
        });
      }
      break;
    default :
      break;
  }
  event.preventDefault();
  event.stopPropagation();
}

function handleMouseOut(event) {
  switch (mode) {
    case 'select-container' :
    case 'select-paragraph' :
      if (!$(event.target).hasClass(['ldrize-ide-container', 'ldrize-ide-paragraph'])) {
        restoreStyle(event.target);
      }
      break;
    default :
      break;
  }
  event.preventDefault();
  event.stopPropagation();
} 
 
function handleClick(event) {
  switch (mode) {
    case 'select-container' :
      cxpathInput.setValue(calcXPath(event.target, null, true));
      evalContainerPath();
      break;
    case 'select-paragraph' :
      if (isInContainer(event.target)) {
        xpathInput.setValue(calcXPath(event.target));
        evalXPath();
      }
      break;
    default : 
      break;
  }
  event.preventDefault();
  event.stopPropagation();
}

var idseq = 0;
var targetStyles = [ 'backgroundColor', 'borderWidth', 'borderStyle', 'borderColor' ];

function overrideStyle(el, style) {
  if (!el) return;
  if (!el._styleCache) {
    el._styleCache = {
      backgroundColor : $(el).css('backgroundColor') || '',
      borderColor : $(el).css('borderColor') || '',
      borderStyle : $(el).css('borderStyle') || 'none',
      borderWidth : $(el).css('borderWidth') || 0
    };
  }
  $(el).css(style);
}

function restoreStyle(el) {
  if (!el) return;
  if (el._styleCache) {
    var style = el._styleCache;
    if (style.backgroundColor=='transparent') style.backgroundColor = '';
    $(el).css(style);
    el._styleCache = undefined;
  }
}

function isInContainer(el) {
  return $(el).parents().index(containerElem)>=0;
}

function countMatchedNodes(xpath) {
  try {
    return doc.evaluate(xpath, doc, null, 7, null).snapshotLength;
  } catch (e) {
    return 0;
  }
}

function getElementsByXPath(xpath) {
  var elements = [];
  try {
    var result = doc.evaluate(xpath, doc, null, 7, null);
    for (var i=0, len=result.snapshotLength; i<len; i++) {
      var n = result.snapshotItem(i);
      if (n.nodeType==1) elements.push(n);
    } 
  } catch (e) {}
  return elements;
}

function calcXPath(el, childPath, single) {
  if (el==containerElem || el.nodeType==9) {
    return cxpathInput.getValue() + '/' + childPath;
  }
  var xpath = calcCompactXPath(el, single);
  if (childPath) xpath += '/'+childPath;
  xpath = xpath.replace(/\/\/+/g, '//');
  if (!single || countMatchedNodes(xpath)==1) {
    return xpath;
  } else {
    xpath = calcStrictXPath(el, single);
    if (childPath) xpath += '/'+childPath;
    return xpath.replace(/\/\/+/g, '//');
  }
}

function calcCompactXPath(el, single) {
  var path;
  if (single && el.id) {
    return '//'+el.tagName.toLowerCase() + "[@id='" + el.id + "']";
  } else if (el.className) {
    var classes = el.className.replace(/(^|\s*)af-xpath-(over|selected|container)(\s*|$)/g, ' ')
                              .replace(/^\s+|\s+$/g)
                              .split(/\s+/);
    var pred = $.map(classes, function(cls) {
      return "contains(concat(' ',@class,' '),' " + cls + " ')";
    }).join(' and ');
    path = el.tagName.toLowerCase() + "[" + pred + "]";
    if (!single || countMatchedNodes(cxpathInput.getValue()+'//'+path)==1) {
      return cxpathInput.getValue()+'//'+path;
    }
  } else {
    path = el.tagName.toLowerCase();
  }
  return calcXPath(el.parentNode, path, single);
}

function calcStrictXPath(el, single) {
  var index = calcElementIndex(el);
  var path = el.tagName.toLowerCase() + (index ? '['+index+']' : '');
  return calcXPath(el.parentNode, path, single);
}

function calcElementIndex(el) {
  if (!el.parentNode) return 0;
  var elements = $(el).parent().find('> '+el.tagName.toLowerCase());
  return elements.length>0 ? elements.index(el)+1 : 0;
}

function clearSelection() {
  $(doc.documentElement)
    .find('.ldrize-ide-mouseover')
      .removeClass('ldrize-ide-mouseover')
      .each(function(){ restoreStyle(this) })
    .end()
    .find('.ldrize-ide-container')
      .removeClass('ldrize-ide-container')
      .each(function(){ restoreStyle(this) })
    .end()
    .find('.ldrize-ide-paragraph')
      .removeClass('ldrize-ide-paragraph')
      .each(function(){ restoreStyle(this) })
    .end();
  containerElem = null;
  cxpathInput.setValue('');
  xpathInput.setValue('');
  mode = 'select-container';
}

function evalContainerPath() {
  $(doc.documentElement)
    .find('.ldrize-ide-container')
      .removeClass('ldrize-ide-container')
      .each(function(){ restoreStyle(this) })
    .end()
    .find('.ldrize-ide-paragraph')
      .removeClass('ldrize-ide-paragraph')
      .each(function(){ restoreStyle(this) })
    .end();
  var cxpath = cxpathInput.getValue();
  $(containerElem = getElementsByXPath(cxpath)[0])
    .addClass('ldrize-ide-container')
    .each(function(){ 
      overrideStyle(this, { 
        backgroundColor : '#ccccff', 
        borderWidth : '1px', 
        borderStyle : 'dotted', 
        borderColor : '#0000ff' 
      });
    });
  xpathInput.setValue('');
  mode = 'select-paragraph';
}

function evalXPath() {
  $(doc.documentElement)
    .find('.ldrize-ide-paragraph')
    .removeClass('ldrize-ide-paragraph')
    .each(function(){ restoreStyle(this) });
  var xpath = xpathInput.getValue();
  $(getElementsByXPath(xpath))
    .addClass('ldrize-ide-paragraph')
    .each(function(){ 
      overrideStyle(this, { 
        backgroundColor : '#ffcccc', 
        borderWidth : '1px', 
        borderStyle : 'dotted', 
        borderColor : '#ffaaaa' 
      });
    });
  mode = 'done';
}

init();
loadContent();

})

